# -*- coding: utf-8 -*-
'''
Created on 7 de Dez de 2011

@author: Francisco do Ó
@number: 5202
'''

'''
O código presente em http://wiki.python.org/jython/DatabaseExamples foi 
usado como base para o desenvolvimento do código presente neste ficheiro

Foi necessário efectuar o download do ficheiro sqlitejdbc-v056.jar
Para correr este programa é necessário que o ficheiro esteja na classpath 
aquando da sua execução
'''
import sys #importa funções do sistema 
import csv #funcionalidades para ficheiros de formato csv
import re #importa biblioteca re para tratar caracteres especiais
import commonModule #módulo commonModule - tratamento dos dados estatísticos 
#Java imports - class e driver manager para SQL
from java.lang import Class
from java.sql  import DriverManager, SQLException

#Listas que vão conter informações dos dados relativos às procuras
one_total = [] 
one_unique = []
two_total = []
two_unique = []
three_unique = []
three_total = []
TEACHERS_DATA = []
#Dados relativos à criação da base de dados e preenchimento da tabela professores
DATABASE    = "opusprimum.db"
JDBC_URL    = "jdbc:sqlite:opusprimum.db"
JDBC_DRIVER = "org.sqlite.JDBC"

TABLE_NAME      = "professores"
TABLE_DROPPER   = "drop table if exists professores;"
TABLE_CREATOR   = '''create table professores (cod_docente integer, nome_docente text,
                                    ultimo_grau text,curso text,categoria text,
                                    regime_tempo text,ano_lectivo integer,
                                    tipo_estab text,nome_estab text);''' 
RECORD_INSERTER = "insert into professores values (?,?,?,?,?,?,?,?,?);"
allData = '''select * from professores'''

#Retirar conteúdo dos ficheiros csv para a lista que posteriormente será
#inserida na base de dados
for fileNumber in range (0,10 + 1):
    filePath = './rebcsv/reb'+ str(fileNumber) +'.csv'
    rowReader = csv.reader(open(filePath, 'rb') ,delimiter = ',')
    rowReader.next() # Skip header line.
    for row in rowReader:
        TEACHERS_DATA.append(row)

'''
@param jdbc_url: URL a usar para a conexão à base de dados
@param driverName: nome do driver utilizado
Dados estes parâmetros o método tenta estabelecer uma ligação à
base de dados
'''   
def getConnection(jdbc_url, driverName):
    try:
        Class.forName(driverName).newInstance()
    except Exception, msg:
        print msg
        sys.exit(-1)

    try:
        dbConn = DriverManager.getConnection(jdbc_url)
    except SQLException, msg:
        print msg
        sys.exit(-1)

    return dbConn

"""
@param dbConn: conexão à base de dados
@param feedstock: lista com os dados a serem introduzidos na tabela
Dada a conexão à base de dados e a lista com o conteúdo dos ficheiros csv
é preenchida a tabela na base de dados.
Depois disso são criadas as listas a serem utilizadas nas respectivas procuras
"""
def populateTable(dbConn, feedstock):
    global one_total, two_total, three_total
    oneWriter = csv.writer(open('./lists/one_total.csv', "wb"))
    twoWriter = csv.writer(open('./lists/two_total.csv', "wb"))
    threeWriter = csv.writer(open('./lists/three_total.csv', "wb"))

    try:
        preppedStmt = dbConn.prepareStatement(RECORD_INSERTER)
        for row in feedstock: 
            for i in range (len(row)):     
                preppedStmt.setString(1, unicode(row[0]))
                preppedStmt.setString(2, unicode(row[1]))
                preppedStmt.setString(3, unicode(re.sub('"', '',row[2])))
                preppedStmt.setString(4, unicode(re.sub('"', '',row[3])))
                preppedStmt.setString(5, unicode(row[4]))
                preppedStmt.setString(6, unicode(row[5]))
                preppedStmt.setString(7, unicode(row[6]))
                preppedStmt.setString(8, unicode(row[7]))
                preppedStmt.setString(9, unicode(row[8]))
                oneRow = str(row[8]) , str(row[6])
                twoRow = str(row[8]) , str(row[4]), str(row[6])
                threeRow = str(row[8]) ,str(row[2]), str(row[6])
                pass
            one_total.append(oneRow)
            two_total.append(twoRow)
            three_total.append(threeRow)
            preppedStmt.addBatch()
    except SQLException, msg:
        print msg
        return False
    oneWriter.writerows(one_total)
    twoWriter.writerows(two_total)
    threeWriter.writerows(three_total)
    
    dbConn.setAutoCommit(False)
    preppedStmt.executeBatch()
    dbConn.setAutoCommit(True)
    return True

'''
Método main - Chama os métodos acima mencionados e fazendo 
uso das listas criadas executa cada uma das três procuras
'''
def main():
    dbConn = getConnection(JDBC_URL, JDBC_DRIVER)
    stmt = dbConn.createStatement()
    try:
        stmt.executeUpdate(TABLE_DROPPER)
        stmt.executeUpdate(TABLE_CREATOR)
    except SQLException, msg:
        print msg

    populateTable(dbConn, TEACHERS_DATA)
    
    #t0 = time.time()
    #print 'tempo inicial = '+ str(t0) + 'segundos'
    commonModule.query_one(one_unique, one_total)
    #print'terminei de tratar os dados para a procura 1'
    #t1 = time.time()
    #print 'tratar dados query 1 = '+ str((t1 - t0)) + 'segundos'
    commonModule.query_two(two_unique, two_total)
    #print'terminei de tratar os dados para a procura 2'
    #t2 = time.time()
    #print 'tratar dados query 2 = '+ str((t2 - t0)) + 'segundos'
    commonModule.query_three(three_unique, three_total)
    #print'terminei de tratar os dados para a procura 3'
    #t3 = time.time()
    #print 'tratar dados query 3 = '+ str((t3 - t0)) + 'segundos'
    print'terminei de tratar os dados para as procuras'
    
    stmt.close()
    dbConn.close()
    

################################################################################
       
if __name__ == '__main__':
    main()
